package cn.qianxun.meta.common.core.map;

import cn.qianxun.meta.common.core.utils.StringUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @Author fuzhilin
 * @Date 2021/12/16 0016 17:23
 * @Description
 */
public class MapToBeanUtil {
    public static <T> List<T> convertMap2Bean(List<Map<String, Object>> map, Class<T> T) {
        List<T> result = null;
        if (CollectionUtils.isEmpty(map)) {
            return result;
        }

        if (!CollectionUtils.isEmpty(map)) {
            result = new ArrayList<>();
            for (int i = 0; i < map.size(); i++) {
                result.add(MapToBeanUtil.convertMap2Bean(map.get(i), T));
            }
        }
        return result;
    }

    public static <T> T convertMap2Bean(Map<String, Object> map, Class<T> T) {
        if (map == null || map.size() == 0) {
            return null;
        }
        //获取map中所有的key值，全部更新成大写，添加到keys集合中,与mybatis中驼峰命名匹配
        Object mvalue = null;
        Map<String, Object> newMap = new HashMap<>();
        Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            String key = it.next().getKey();
            mvalue = map.get(key);
            newMap.put(key.toUpperCase(Locale.US), mvalue);
        }

        T bean = null;
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(T);
            bean = T.newInstance();
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (int i = 0, n = propertyDescriptors.length; i < n; i++) {
                PropertyDescriptor descriptor = propertyDescriptors[i];
                String propertyName = descriptor.getName();
                String upperPropertyName = propertyName.toUpperCase();

                if (newMap.keySet().contains(upperPropertyName)) {
                    Object value = newMap.get(upperPropertyName);
                    //这个方法不会报参数类型不匹配的错误。
                    BeanUtils.copyProperty(bean, propertyName, value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bean;
    }


    /**
     * 对象转map
     *
     * @param obj
     * @return
     */
    public static Map<String, Object> objToMap(Object obj) {

        Map<String, Object> map = new HashMap<String, Object>();
        // 获取f对象对应类中的所有属性域
        Field[] fields = obj.getClass().getDeclaredFields();
        for (int i = 0, len = fields.length; i < len; i++) {
            String varName = fields[i].getName();
            try {
                // 获取原来的访问控制权限
                boolean accessFlag = fields[i].isAccessible();
                // 修改访问控制权限
                fields[i].setAccessible(true);
                // 获取在对象f中属性fields[i]对应的对象中的变量
                Object o = fields[i].get(obj);
                /*if (o != null) {
                    map.put(varName, o.toString());
                }*/
                map.put(varName, StringUtils.isNull(o) ? "" : o.toString());

                // 恢复访问控制权限
                fields[i].setAccessible(accessFlag);
            } catch (IllegalArgumentException ex) {
                ex.printStackTrace();
            } catch (IllegalAccessException ex) {
                ex.printStackTrace();
            }
        }
        return map;
    }


    /**
     * list对象转maps
     *
     * @param objects
     * @return
     */
    public static List<Map<String, Object>> objToMaps(List<Object> objects) {
        List<Map<String, Object>> maps = new ArrayList<>();
        if (!CollectionUtils.isEmpty(objects)) {
            for (Object object : objects) {
                Map<String, Object> map = objToMap(object);
                maps.add(map);
            }
        }
        return maps;
    }


}
